home *** CD-ROM | disk | FTP | other *** search
- COMMENT \
- Filter a file, expanding tabs to blanks up to the next column which is a
- multiple of 8.
-
- Usage: detab <inputfile >outputfile
-
- {Adapted from a disassembly of the IBM utility MORE.COM and commented
- with a view to being a model for further simple filters.}
- [20-Jan-84]
- \
-
- assume cs:detabc,ds:detabc,es:detabc,ss:detabc
- detabc segment para public 'code'
-
- include dos.inc
- include ascii.inc
-
- org 100h
- MAXBUFFER equ 4096 ; Buffer size (freely variable)
-
- detab:
- mov ah,$DOS_GETVERSION
- int $DOS
- xchg ah,al
- cmp ax,0200h ; DOS 2.00 or later?
- jnb cont ; jump if version >= 2.00
- mov dx,offset baddos
- mov ah,$DOS_STROUT ; print string
- int $DOS
- mov ah,$DOS_EXIT
- mov al,1 ; return code
- int $DOS ; terminate
-
- cont:
- mov byte ptr numrows,25
- mov ah,0fh ; request current video state
- int $VIDEO
- mov numcols,ah ; save number of columns on display
- mov bx,$STDIN ; standard input handle
- mov ah,$DOS_DUP ; dup handle
- int $DOS
- mov bp,ax ; save duplicate handle
- mov ah,$DOS_CLOSE2 ; close standard input
- int $DOS
- mov bx,$STDERR ; standard error handle
- mov ah,$DOS_DUP ; dup handle
- int $DOS
-
- nextbf:
- cld ; clear direction flag
- mov dx,offset buffer ; buffer address
- mov cx,MAXBUFFER ; count of bytes to read
- mov bx,bp ; duplicate of standard input handle
- mov ah,$DOS_READ2 ; byte stream
- int $DOS ; read a byte string
- or ax,ax ; set condition flags based on byte count
- jnz gotch ; jump if got some bytes
- exit:
- mov ah,$DOS_EXIT ; all done, no more data
- mov al,0 ; return code
- int $DOS ; terminate
-
- gotch:
- mov cx,ax ; byte count
- mov si,dx ; buffer address ???
- nextch:
- lodsb ; load byte at 0(si), then increment si
- cmp al,.CR ; Hit CR yet?
- jne nocr ; Jump if not CR
- mov byte ptr colnum,1 ; Was CR, set column_number = 1
- jmp short printch ; go print the character
- nocr:
- cmp al,.LF ; Hit end-of-line yet?
- jne nolf ; Jump if not LF
- inc rownum ; Hit LF, increment row number
- jmp short printch ; go print the character
- nolf:
- cmp al,.BS ; Hit backspace?
- jne nobs ; Jump if not BS
- cmp byte ptr colnum,1 ; At beginning of line?
- jz printch ; Yes, just print character
- dec colnum ; No, decrement column number because of BS
- jmp short printch ; Go print the character
- nobs:
- cmp al,.HT ; Hit tab?
- jne notab ; Jump if not tab.
- mov ah,colnum ; Was tab, get column number
- add ah,7 ; column number + 7
- and ah,not 7 ; clear right 3 bits, effectively advancing
- inc ah ; to multiple of 8, then add 1 more
- mov colnum,ah ; and update column number
- jmp short printch ; Go print the character
- notab:
- cmp al,.BEL ; Hit a bell?
- je printch ; Yes, just print it
- inc colnum ; Not special character, so just increment
- mov ah,colnum ; column number and remember it
- cmp ah,numcols ; At end of screen line yet?
- jbe printch ; jump if not
- inc rownum ; At end of screen line, so start a new row
- mov byte ptr colnum,1 ; and reset to column 1
- printch:
- mov dl,al ; the character to output
- mov ah,$DOS_CONOUT ; print char
- int $DOS
- mov ah,rownum
- cmp ah,numrows ; At end of screen yet?
- jb loopch ; Jump if not
- mov byte ptr colnum,1 ; Reset row/column to home
- mov byte ptr rownum,1 ; position
- dec si ; Backup in buffer
- inc cx ; and increase byte count (why ??)
- loopch:
- dec cx ; Reduce byte count since we just output one
- jbe longbf ; Exit loop if count <= 0
- jmp nextch ; Otherwise loop for next character
- longbf:
- jmp nextbf ; Loop for next buffer
-
- numrows db 24 ; Default screen rows
- numcols db 80 ; Default screen columns
- rownum db 01 ; Starting screen row
- colnum db 01 ; Starting screen column
- db 00h,00h,00h,00h,00h
- baddos db "DETAB: Incorrect DOS version"
- db " -- must run under DOS 2.0 or later"
- crlf db .CR,.LF,"$"
-
- buffer db MAXBUFFER dup (0) ; Input buffer
-
- detabc ends
- end detab